home *** CD-ROM | disk | FTP | other *** search
- /*
- ** POSIXDIR.C - POSIX-style directory processing
- **
- ** Original Copyright 1988-1991 by Bob Stout as part of
- ** the MicroFirm Function Library (MFL)
- **
- ** This subset version is functionally identical to the
- ** version originally published by the author in Tech Specialist
- ** magazine and is hereby donated to the public domain.
- */
-
- #include <string.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <io.h>
- #include <errno.h>
- #include "dirent.h"
-
- #define _NDIRS 20
- #define SUCCESS 0
- #define ERROR -1
-
- #define LAST_CHAR(s) ((char *)(s))[strlen(s) - 1]
-
- int DFerr;
- DOS_DIR _DIRS[_NDIRS]; /* Initilize DOS_DIR array to zeros */
-
- /*
- ** Convert Unix-style pathnames to DOS-style
- */
-
- static char *unix2dos(char *path)
- {
- char *p;
-
- while (NULL != (p = strchr(path, '/')))
- *p = '\\';
- return path;
- }
-
- /****************************************************************/
- /* */
- /* opendir() */
- /* */
- /* Function: Open a directory for reading. */
- /* */
- /* Parameters: 1 - Directory name. May include path spec. */
- /* */
- /* Returns: Pointer to a DOS_DIR typedef'ed structure, similar */
- /* to fopen() returning a FILE pointer. */
- /* */
- /* NULL if error, DFerr set as follows: */
- /* SUCCESS - No error */
- /* ENOENT - Could not locate directory or contents */
- /* ENOTDIR - Not a directory */
- /* ENOMEM - Too many directories already open */
- /* */
- /* Side effects: The dd_size element of the DOS_DIR structure */
- /* will contain a number representing the total */
- /* number of entries in the directory. The */
- /* dd_loc element will be set to zero since */
- /* no elements have, as yet, been read. */
- /* */
- /****************************************************************/
-
- DOS_DIR *opendir(char *fname)
- {
- int i;
- unsigned n = 0;
- char nametmp[13], *p;
- struct DSTRUCT dstruct;
-
- for (i = 0; i < _NDIRS; ++i)
- {
- if (!_DIRS[i].dd_fd)
- break;
- }
- if (_NDIRS <= i)
- {
- DFerr = ENOMEM;
- return NULL;
- }
-
- unix2dos(fname);
- if (':' == fname[1] && 1 < strlen(fname))
- p = &fname[2];
- else p = fname;
- while ('\\' == LAST_CHAR(p) && 1 < strlen(p))
- LAST_CHAR(p) = '\0';
-
- if (strcmp(p, "\\") && strlen(p))
- {
- if (NULL == (rfind_1st(fname, FA_ANY, &_DIRS[i].dd_buf)))
- {
- DFerr = ENOENT;
- return NULL;
- }
- if (!(FA_DIREC & _DIRS[i].dd_buf.ATTRIBUTE))
- {
- DFerr = ENOTDIR;
- return NULL;
- }
- }
- strcpy(_DIRS[i].dd_dirname, fname);
- if (!strlen(p))
- strcat(_DIRS[i].dd_dirname, ".");
- if ('\\' != LAST_CHAR(_DIRS[i].dd_dirname))
- strcat(_DIRS[i].dd_dirname, "\\");
- strcat(strupr(_DIRS[i].dd_dirname), "*.*");
- if (NULL == rfind_1st(_DIRS[i].dd_dirname, FA_ANY, &_DIRS[i].dd_buf))
- {
- DFerr = ENOENT;
- return NULL;
- }
- memcpy(&dstruct, &_DIRS[i].dd_buf, sizeof(struct DSTRUCT));
- do
- {
- ++n;
- } while (rfind_nxt(&_DIRS[i].dd_buf));
- memcpy(&_DIRS[i].dd_buf, &dstruct, sizeof(struct DSTRUCT));
- _DIRS[i].dd_size = n;
- _DIRS[i].dd_loc = 0;
- _DIRS[i].dd_fd = i + 1;
- DFerr = SUCCESS;
- return &_DIRS[i];
- }
-
- /****************************************************************/
- /* */
- /* closedir() */
- /* */
- /* Function: Close a preeviously opened directory. */
- /* */
- /* Parameters: 1 - DOS_DIR pointer of directory to close. */
- /* */
- /* Returns: SUCCESS or ERROR. */
- /* */
- /****************************************************************/
-
- int closedir(DOS_DIR *dirp)
- {
- if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd)
- {
- DFerr = EBADF;
- return ERROR;
- }
- memset(dirp, 0, sizeof(DOS_DIR));
- return SUCCESS;
- }
-
- /****************************************************************/
- /* */
- /* rewinddir() */
- /* */
- /* Function: Reset an open DOS_DIR to its first entry. */
- /* */
- /* Parameters: 1 - DOS_DIR pointer of directory to rewind. */
- /* */
- /* Returns: SUCCESS or ERROR. */
- /* */
- /****************************************************************/
-
- int rewinddir(DOS_DIR *dirp)
- {
- if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd)
- {
- DFerr = EBADF;
- return ERROR;
- }
- rfind_1st(dirp->dd_dirname, FA_ANY, &(dirp->dd_buf));
- dirp->dd_loc = 0;
- return SUCCESS;
- }
-
- /****************************************************************/
- /* */
- /* seekdir() */
- /* */
- /* Function: Point to a selected entry in a DOS_DIR. */
- /* */
- /* Parameters: 1 - DOS_DIR pointer of directory to rewind. */
- /* 2 - Offset of entry to seek */
- /* 3 - Origin of offset */
- /* */
- /* Returns: A DSTRUCT pointer, same as returned by rfind_1st() */
- /* and rfind_nxt(). */
- /* */
- /* NULL if error, DFerr set as follows: */
- /* SUCCESS - No error */
- /* EBADF - Bad file (DOS_DIR) pointer */
- /* EACCES - Illegal origin specification */
- /* EOF - Attempt to seek past end of directory */
- /* */
- /****************************************************************/
-
- struct DSTRUCT *seekdir(DOS_DIR *dirp, int offset, int origin)
- {
- int i, loc;
-
- if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd)
- {
- DFerr = EBADF;
- return NULL;
- }
- switch (origin)
- {
- case SEEK_SET:
- loc = offset + 1;
- break;
- case SEEK_CUR:
- loc = dirp->dd_loc + offset;
- break;
- case SEEK_END:
- loc = dirp->dd_size + offset;
- break;
- default:
- DFerr = EACCES;
- return NULL;
- }
-
- if (loc > (int)dirp->dd_size || 0 >= loc)
- {
- DFerr = EOF;
- return NULL;
- }
-
- rewinddir(dirp);
- for (i = 0; i < loc; ++i)
- readdir(dirp);
-
- DFerr = SUCCESS;
- return (&(dirp->dd_buf));
- }
-
- /****************************************************************/
- /* */
- /* readdir() */
- /* */
- /* Function: Reads entries from an open directory. */
- /* */
- /* Parameters: 1 - DOS_DIR pointer of directory to read. */
- /* */
- /* Returns: A DSTRUCT pointer, same as returned by rfind_1st() */
- /* and rfind_nxt(). */
- /* */
- /* NULL if error, DFerr set as follows: */
- /* SUCCESS - No error */
- /* EBADF - Bad file (DOS_DIR) pointer */
- /* EOF - Attempt to read past end of directory */
- /* */
- /* Side effects: The dd_loc element of the DOS_DIR structure */
- /* will contain a number representing which */
- /* element of the directory was returned. It may */
- /* range from 1 to dd_size. */
- /* */
- /****************************************************************/
-
- struct DSTRUCT *readdir(DOS_DIR *dirp)
- {
- if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd)
- {
- DFerr = EBADF;
- return NULL;
- }
- if (0 == dirp->dd_loc || NULL != rfind_nxt(&(dirp->dd_buf)))
- {
- dirp->dd_loc += 1;
- DFerr = SUCCESS;
- return (&(dirp->dd_buf));
- }
- else
- {
- DFerr = EOF;
- return NULL;
- }
- }
-